// wijmo 组件
import './Wijmo.scss'
import "@grapecity/wijmo.cultures/wijmo.culture.zh"

import { useEffect, useState } from 'react'
import { useRequest } from 'alova/client'
import { Dropdown, Pagination, App } from 'antd'
import { useEventEmitter, useReactive, useDebounceFn, useLocalStorageState } from 'ahooks'

import { PivotEngine } from '@grapecity/wijmo.olap'
import { PivotGrid } from '@grapecity/wijmo.react.olap'
import { CollectionView } from '@grapecity/wijmo'
import { Row, GroupRow } from '@grapecity/wijmo.grid'
import { ListBox } from '@grapecity/wijmo.react.input'
import { FlexGridFilter } from "@grapecity/wijmo.react.grid.filter"
import { GroupPanel } from "@grapecity/wijmo.react.grid.grouppanel"
import { FlexGrid, FlexGridColumn, FlexGridCellTemplate } from '@grapecity/wijmo.react.grid'

import { Http } from '../API'
import { ModelBox, DrawerBox } from '../Model'
import { eventHandlers, getDataMap, CustonGroup, initListBox, initTopDom, initSearchValue, initSortValue } from './WijmoCommon'

export const WijmoBase = ({ Config }) => {
    const { notification } = App.useApp()
    const { get, pos, put, del, configuration, initParameter, columns, optionsBtn, params, sortCriteria } = Config
    const { groupPanel, addTop, addBtm, addSum, addIndex, topText, btmText, group, sort, filter } = initParameter

    const InitWijmo = useReactive({ init: null, isDragEnabled: true })

    const { send: getApi } = useRequest(({ url, params }) => Http({ url, params }), { immediate: false })
    const { send: posApi } = useRequest(({ url, params }) => Http({ url, params }), { immediate: false })
    const { send: putApi } = useRequest(({ url, params }) => Http({ url, params }), { immediate: false })
    const { send: delApi } = useRequest(({ url, params }) => Http({ url, params }), { immediate: false })

    const [Data, setData] = useState([])
    const [Search, setSearch] = useState([])

    const [SortData, setSortData] = useState()
    const [SearchData, setSearchData] = useState()

    const [OptionsCall, setOptionsCall] = useState()
    const [DrawerCall, setDrawerCall] = useState()

    const [PageNumebr, setPageNumber] = useState({ pageIndex: 1, pageSize: params.pageSize })
    const [total, setTotal] = useState(0)

    const init = async (e, status) => {
        InitWijmo.init = e
        // 初始化排序条件
        const initSort = initSortValue(sortCriteria)
        InitWijmo.initSort = initSort
        setSortData(initSort)
        // 初始化搜索条件
        const initSearch = initSearchValue(columns)
        InitWijmo.initSearch = initSearch
        setSearchData(initSearch)


        setSearch(columns.filter(v => !v.hideInSearch))
        if (addTop) e.columnHeaders.rows.push(new Row())
        if (!status && (addBtm || addSum)) e.columnFooters.rows.push(addSum ? new GroupRow() : new Row())
        initTopDom(e, InitWijmo)
    }
    const getData = async (sortData, searchData) => {
        const initParmars = { ...params, ...sortData, ...searchData, ...PageNumebr }
        const obj = await getApi({ url: get, params: initParmars })
        const data = new CollectionView(obj.list, { groupDescriptions: group, sortDescriptions: sort })
        setTotal(obj.total)
        setData(data)
    }

    const { run } = useDebounceFn(() => getData(SortData, SearchData), { wait: 500 })
    useEffect(() => run, [PageNumebr, SortData, SearchData])

    const OptionsConfig = (e, btnData) => {
        const handler = eventHandlers[e]
        if (handler) {
            handler({
                ModalEvent,
                setOptionsCall,
                setDrawerCall,
                init,
                btnData,
                InitWijmo,
                columns,
                Data,
                Search,
                sortCriteria,
                SortData,
                SearchData,
                params
            })
        }
        else console.log(`未找到事件 '${e}' 的处理程序`)
    }

    const ModalEvent = useEventEmitter()
    ModalEvent.useSubscription(val => {
        const { data, type } = val
        const { init: wijmoInit } = InitWijmo
        if (type === 'Added') {
            posApi({ url: pos, params: data })
                .then(() => {
                    init(wijmoInit, true)
                    ModalEvent.emit({ type: 'offModal' })
                    notification.info({ key: 'success', message: '操作成功!', description: '已成功添加新数据!' })
                })
                .catch(() => {
                    ModalEvent.emit({ type: 'offLoading' })
                    notification.error({ key: 'error', message: '操作失败!', description: '数据添加失败,请重试!' })
                })
        }
        if (type === 'Delete') {
            delApi({ url: del, params: { uuid: data.uuid } })
                .then(() => {
                    init(wijmoInit, true)
                    ModalEvent.emit({ type: 'offModal' })
                    notification.info({ key: 'success', message: '操作成功!', description: '当前数据已删除!' })
                })
                .catch(() => {
                    ModalEvent.emit({ type: 'offLoading' })
                    notification.error({ key: 'error', message: '操作失败!', description: '数据删除失败,请重试!' })
                })
        }
        if (type === 'Modify') {
            putApi({ url: put, params: data })
                .then(() => {
                    init(wijmoInit, true)
                    ModalEvent.emit({ type: 'offModal' })
                    notification.info({ key: 'success', message: '操作成功!', description: '当前数据已更新!' })
                })
                .catch(() => {
                    ModalEvent.emit({ type: 'offLoading' })
                    notification.error({ key: 'error', message: '操作失败!', description: '数据修改失败,请重试!' })
                })
        }
        if (type === 'Refresh') init(InitWijmo.init, true)
        if (type === 'Search') setSearchData(data)
        if (type === 'SeaRef') setSearchData(InitWijmo.initSearch)
        if (type === 'Sort') setSortData(data)
        if (type === 'SorRef') setSortData(InitWijmo.initSort)
        if (type === 'ModelBox') {
            setOptionsCall({
                title: data.title,
                type: data.type,
                data: { ...data, ...Data.currentItem },
                width: data.width || 1000
            })
        }
    })

    return (
        <div className="WijmoClass WijmoClassBase">
            {groupPanel && <GroupPanel className="GroupPanel" grid={InitWijmo.init} placeholder="将列拖动到此处以创建组(最多6组)" />}

            <Dropdown menu={{ items: optionsBtn(OptionsConfig) }} trigger={['contextMenu']}>
                <div>
                    <FlexGrid
                        itemsSource={Data}
                        initialized={init}
                        {...configuration}
                    >
                        <FlexGridCellTemplate cellType="TopLeft" template={() => <div className='TopText'>{topText}</div>} />
                        {(addBtm || addSum) && <FlexGridCellTemplate cellType="BottomLeft" template={() => btmText} />}
                        <FlexGridCellTemplate cellType="RowHeader" template={e => addIndex ? e.row.index + 1 : ''} />
                        {filter && <FlexGridFilter />}
                        {columns.map(({ dataIndex, title, valueEnum, valueType, fieldNames, hideInTable, ...config }) => {
                            if (valueType === 'Hidden') return false
                            if (hideInTable) return false
                            return (
                                <FlexGridColumn
                                    {...config}
                                    key={dataIndex}
                                    header={title}
                                    binding={dataIndex}
                                    dataMap={getDataMap(valueEnum || '', fieldNames)}
                                >
                                    <FlexGridCellTemplate cellType="Group" template={e => CustonGroup(e, columns)} />
                                    <FlexGridCellTemplate cellType="ColumnFooter" template={e => CustonGroup(e, columns)} />
                                </FlexGridColumn>
                            )
                        })}
                    </FlexGrid>
                </div>
            </Dropdown>

            {total / PageNumebr.pageSize > 1 &&
                <div className='Pagination'>
                    <Pagination
                        current={PageNumebr.pageIndex}
                        pageSize={PageNumebr.pageSize}
                        pageSizeOptions={[10, 100, 1000, 10000, 100000]}
                        showSizeChanger
                        align="end"
                        total={total}
                        onChange={(e, s) => setPageNumber({ pageIndex: e, pageSize: s })}
                    />
                </div>
            }

            <div className="column-picker-div">
                <ListBox className="column-picker" initialized={e => initListBox(e, InitWijmo)} />
            </div>

            <ModelBox OptionsCall={OptionsCall} ModalEvent={ModalEvent} />
            <DrawerBox OptionsCall={DrawerCall} ModalEvent={ModalEvent} />
        </div>
    )
}

// 数据枢纽组件
export const WijmoOLAP = ({ Config }) => {
    const { get, params, initCom, configuration, combination, optionsBtn, gridConfig } = Config
    const [Combination] = useLocalStorageState('Combination', { listenStorageChange: true })

    const [Search, setSearch] = useState([])
    const [SearchData, setSearchData] = useState()
    const [OptionsCall, setOptionsCall] = useState()
    const [DrawerCall, setDrawerCall] = useState()
    const InitWijmo = useReactive({ init: null })

    const { send: getApi } = useRequest(({ url, params }) => Http({ url, params }), { immediate: false })
    const init = (init) => {
        InitWijmo.init = init
        // 初始化搜索条件
        const initSearch = initSearchValue(gridConfig.columns)
        InitWijmo.initSearch = initSearch
        setSearchData(initSearch)
        setSearch(gridConfig.columns.filter(v => !v.hideInSearch))
    }

    const getData = async (searchData) => {
        const initParmars = { ...params, ...searchData }
        const data = await getApi({ url: get, params: initParmars })
        InitWijmo.Data = new PivotEngine({ itemsSource: data.list, ...combination[initCom].data })
    }

    const OptionsConfig = (e, btnData) => {
        const handler = eventHandlers[e]
        if (handler) {
            handler({
                btnData,
                ModalEvent,
                setOptionsCall,
                setDrawerCall,
                init,
                InitWijmo,
                Search,
                SearchData,
                combination,
                initCom,
            })
        }
        else console.log(`未找到事件 '${e}' 的处理程序`)
    }


    const ModalEvent = useEventEmitter()
    ModalEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'SwitchGrouping') {
            if (combination[data]) InitWijmo.Data.viewDefinition = JSON.stringify(combination[data].data)
            else InitWijmo.Data.viewDefinition = Combination.find(v => v.key === data).data
        }


        if (type === 'Search') setSearchData(data)
        if (type === 'SeaRef') setSearchData(InitWijmo.initSearch)
    })

    const { run } = useDebounceFn(() => getData(SearchData), { wait: 500 })
    useEffect(() => run, [SearchData])

    return (
        <div className='WijmoClass WijmoClassOLAP'>
            <Dropdown menu={{ items: optionsBtn(OptionsConfig) }} trigger={['contextMenu']}>
                <div>
                    <PivotGrid initialized={init} itemsSource={InitWijmo.Data} {...configuration} />
                </div>
            </Dropdown>
            <ModelBox OptionsCall={OptionsCall} ModalEvent={ModalEvent} />
            <DrawerBox OptionsCall={DrawerCall} ModalEvent={ModalEvent} />
        </div>
    )
}
